package client

import (
	"errors"
	"flag"
	"log"
	"path/filepath"
	"sync"

	"k8s.io/client-go/discovery"
	"k8s.io/client-go/dynamic"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/util/homedir"
)

type k8sClient struct {
	clientSet       kubernetes.Interface
	dynamicClient   dynamic.Interface
	discoveryClient *discovery.DiscoveryClient
	restConfig      *rest.Config
}

var (
	once sync.Once
	c    k8sClient
)

func NewClient() (err error) {
	once.Do(func() {
		// 1.加载配置文件
		var (
			config     *string
			restConfig *rest.Config
		)

		if home := homedir.HomeDir(); home != "" {
			config = flag.String("kubeConfig", filepath.Join(home, ".kube", "config"), "")
		} else {
			log.Fatal("kubeConfig not found")
			err = errors.New("kubeConfig not found")
			return
		}
		flag.Parse()
		restConfig, err = clientcmd.BuildConfigFromFlags("", *config)
		if err != nil {
			log.Fatal(err.Error())
			return
		}

		// 2.实例化各种客户端
		//clientSet
		c.clientSet, err = kubernetes.NewForConfig(restConfig)
		if err != nil {
			log.Fatal(err.Error())
			return
		}

		//dynamicClient
		c.dynamicClient, err = dynamic.NewForConfig(restConfig)
		if err != nil {
			log.Fatal(err.Error())
			return
		}

		//discoveryClient
		c.discoveryClient, err = discovery.NewDiscoveryClientForConfig(restConfig)
		if err != nil {
			log.Fatal(err.Error())
			return
		}

		// 3. 直接返回restConfig
		c.restConfig = restConfig
	})

	return
}

func GetClientSet() (clientSet kubernetes.Interface) {
	clientSet = c.clientSet
	return
}

func GetDynamicClient() (dynamicClient dynamic.Interface) {
	dynamicClient = c.dynamicClient
	return
}

func GetDiscoveryClient() (discoveryClient *discovery.DiscoveryClient) {
	discoveryClient = c.discoveryClient
	return
}

func GetRestConfig() (restConfig *rest.Config) {
	restConfig = c.restConfig
	return
}
